/*osen
 * server_session.cpp
 *
 *  Created on: Dec 26, 2013
 *      Author: killerg
 */

#include "bill_deps.h"
#include "server_session.h"
#include "bill.h"
#include "bill_cfg.h"
#include "bill_console.h"
#include "code.h"

#include "share/msg.h"
#include "share/clock.h"
#include "share/db_mgr.h"

void handle_slogon(server_session_t* sess, sb::SMsg* msg) {
    int serverid = msg->logon().serverid();
    if (serverid < 0) {
        sess->_trans->disconnect();
        return;
    }

    auto info = g_svrmgr->serverinfos.get(serverid);
    if (NULL == info) {
        info = new server_info_t;
        g_svrmgr->serverinfos.set(serverid, info);
    } else if (info->sess) {
    	sess->_trans->disconnect();
    	return;
    }
    sess->serverid = serverid;

    info->sess = sess;
    CREATE_SB_BMSG(BLogon, logon);
    logon->set_ok(true);
    sess->send_msg(___msg);
}

void handle_screateplayer(server_session_t* sess, sb::SMsg* msg) {
    if (sess->serverid < 0) {
        sess->_trans->disconnect();
        return;
    }

    const auto &createplayer = msg->createplayer();
    for (int i=0; i<createplayer.createplayer_size(); ++i) {
        player_info_t info;
        info.playername = createplayer.createplayer(i).playername();
        info.playerid = createplayer.createplayer(i).playerid();
        g_svrmgr->refresh_player_info(sess->serverid, createplayer.createplayer(i).account(), info);
    }
}

void handle_susecode(server_session_t* sess, sb::SMsg* msg) {
    if (sess->serverid < 0) {
        sess->_trans->disconnect();
        return;
    }

    const string &code = msg->usecode().code();
    const string &account = msg->usecode().account();
    int64_t playerid = msg->usecode().playerid();

    if (g_bill.code->all_code.count(code) == 0) {
        CREATE_SB_BMSG(BUseCode, usecode);
        usecode->set_playerid(playerid);
        usecode->set_code(code);
        usecode->set_errcode(sb::BUseCode_ErrCode_NotExist);
        sess->send_msg(___msg);
        return;
    }

    if (g_bill.code->used_code.count(code) > 0) {
        CREATE_SB_BMSG(BUseCode, usecode);
        usecode->set_playerid(playerid);
        usecode->set_code(code);
        usecode->set_errcode(sb::BUseCode_ErrCode_Used);
        sess->send_msg(___msg);
        return;
    }

    g_bill.code->used_code.insert(code);
    g_bill.code->chged = true;

    Json::Value log;
    log["objtype"] = "code";
    log["code"] = code;
    log["account"] = account;
    log["playerid"] = Json::Int64(playerid);

    int32_t serverid = sess->serverid;
    g_bill.db->add(
            fmt_cstr("code:%s", code.c_str()),
            log,
            [code, serverid, account, playerid](db_error_t err){
                switch (err) {
                case DBE_Success:
                {
                    auto svrinfo = g_svrmgr->serverinfos.get(serverid);
                    if (NULL == svrinfo || NULL == svrinfo->sess) {
                        return;
                    }

                    CREATE_SB_BMSG(BUseCode, usecode);
                    usecode->set_playerid(playerid);
                    usecode->set_code(code);
                    usecode->set_errcode(sb::BUseCode_ErrCode_Success);
                    svrinfo->sess->send_msg(___msg);
                }
                    break;
                default:
                {
                    g_bill.code->used_code.erase(code);

                    auto svrinfo = g_svrmgr->serverinfos.get(serverid);
                    if (NULL == svrinfo || NULL == svrinfo->sess) {
                        return;
                    }

                    CREATE_SB_BMSG(BUseCode, usecode);
                    usecode->set_playerid(playerid);
                    usecode->set_code(code);
                    usecode->set_errcode(sb::BUseCode_ErrCode_ContractService);
                    svrinfo->sess->send_msg(___msg);
                }
                    break;
                }
            });

}

void handle_sping(server_session_t* sess, sb::SMsg* msg) {

}

void handle_sreward(server_session_t* sess, sb::SMsg* msg) {
	evbuffer_add_printf(
			g_bill.console->_tran->output,
			"account:%s rewardid:%d content:%s result:%s\r\n",
			msg->reward().account().c_str(),
			msg->reward().reward(),
			msg->reward().content().c_str(),
			msg->reward().result().c_str());
}

bool server_session_t::send_msg(sb::BMsg* msg) {
    return g_bill.sessmgr->send_msg(this, msg);
}

void server_session_t::update() {
    if (serverid < 0)
        return;

    auto info = g_svrmgr->serverinfos.get(serverid);
    if (NULL == info)
        return;

    if (!info->orders.empty()) {
        CREATE_SB_BMSG(BOrder, order);
        for (int i=0; i<g_cfg->OrderPerSec && !info->orders.empty(); ++i) {
            auto oorder = order->add_order();

            auto tosend = info->orders.front();
            info->orders.pop_front();

            oorder->set_orderid(tosend->orderId);
            oorder->set_payfee(tosend->payfee);
            oorder->set_playerid(tosend->playerid);
            if (!tosend->machinecode.empty())
            	oorder->set_machinecode(tosend->machinecode);

            safe_del(tosend);
            ++g_svrmgr->order_post;
        }
        send_msg(___msg);
    }
}

void server_session_t::on_connect() {
    serverid = -1;
}

void server_session_t::on_disconnect() {
    if (serverid < 0)
        return;

    auto info = g_svrmgr->serverinfos.get(serverid);
    if (NULL == info)
        return;

    info->sess = NULL;
}


bool serversess_mgr_t::init() {
    bool ret = base::init(
    		g_cfg->ListenServerIp.c_str(),
    		g_cfg->ListenServerPort,
    		200,
    		100,
    		5.0f,
    		0xffffffff,
    		false
    		);

    ret = ret && base::reg(sb::ID_SLogon,         	handle_slogon);
    ret = ret && base::reg(sb::ID_SCreatePlayer,    handle_screateplayer);
    ret = ret && base::reg(sb::ID_SUseCode,         handle_susecode);
    ret = ret && base::reg(sb::ID_SPing,        	handle_sping);
    ret = ret && base::reg(sb::ID_SReward,        	handle_sreward);

    return ret;
}
